﻿Imports Bitcoin
Imports MultiBitcoin
Imports Newtonsoft.Json
Imports System.Net
Imports System.IO

Public Class Form1

    Public Divisor As Long = 100000000 '100 Million
    Private _Balance As Long = 0
    Public Addresses As String = String.Empty
    Public Const File_AddressDat As String = "addresses.dat"
    Public Const File_LogDat As String = "log.dat"
    Public Const Title As String = "Bitcoin RT"
    Public Const CoinbaseAPIURL As String = "https://coinbase.com/api/v1/prices/spot_rate"
    Public Const BlockchainMultiAddressURL = "https://blockchain.info/multiaddr?active={0}"

    Sub UpdateData()
        Me.Cursor = Cursors.WaitCursor
        Try
            Dim Spot As String = GetSpotPrice()
            Dim Balance As Long = 0
            Dim bitcoins As New MultiBitcoin.Bitcoin
            Dim JSON As String = String.Empty

            Using WC As New WebClient
                Dim URI As String = String.Format(BlockchainMultiAddressURL, Addresses)
                JSON = WC.DownloadString(URI)
            End Using

            bitcoins = JsonConvert.DeserializeObject(Of MultiBitcoin.Bitcoin)(JSON)

            For Each Address As MultiBitcoin.Address In bitcoins.addresses
                Balance += Address.final_balance
            Next

            txtBalance.Text = String.Format("{0}", Balance / Divisor)
            txtCurrentPrice.Text = String.Format("{0}", FormatCurrency(Spot, 2, TriState.UseDefault, TriState.UseDefault, TriState.True))
            txtValue.Text = String.Format("{0}", FormatCurrency((Balance / Divisor) * Spot, 2, TriState.UseDefault, TriState.UseDefault, TriState.True))

            If _Balance <> Balance And _Balance <> 0 Then
                NotifyIcon1.BalloonTipIcon = ToolTipIcon.Info
                NotifyIcon1.BalloonTipText = "New balance is:" & Balance / Divisor & " " & CalcBalanceChange(_Balance / Divisor, Balance / Divisor)
                NotifyIcon1.BalloonTipTitle = "Bitcoin RT - Balance change notification"
                NotifyIcon1.ShowBalloonTip(10000)
            End If

            _Balance = Balance

        Catch ex As Exception
            Log(ex)
        End Try
        Me.Cursor = Cursors.Default
    End Sub

    Sub SetWindowText()
        If Not Me.Focused Then
            Me.Text = txtValue.Text
        Else
            If Me.WindowState = FormWindowState.Minimized Then
                Me.Text = txtValue.Text
            ElseIf Me.WindowState = FormWindowState.Normal Then
                Me.Text = Title
            Else
                Me.Text = Title
            End If
        End If
    End Sub

    Function GetSpotPrice() As String
        Dim SpotPrice As New Bitcoin.CoinBase.SpotPrice
        Try
            Using WC As New WebClient
                Dim JSON As String = WC.DownloadString(CoinBaseAPIURL)
                SpotPrice = JsonConvert.DeserializeObject(Of CoinBase.SpotPrice)(JSON)
            End Using
        Catch ex As Exception
            Log(ex)
        End Try
        Return SpotPrice.amount
    End Function

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        ShowLogMenuItem.Checked = False
        Me.Show()
        LoadAddresses()
        If (Addresses.Length < 1) Then
            AddAddress()
        End If
        Timer1.Interval = 1
        Timer1.Enabled = True
        ListBox1.Items.Add("Fetching Data...")
        ListBox1.SelectedIndex = ListBox1.Items.Count - 1
    End Sub

    Public Sub LoadAddresses()
        Log("Loading Addresses...")
        Try
            If File.Exists(File_AddressDat) Then
                Dim Addies As String() = File.ReadAllLines(File_AddressDat)
                Form2.txtAddresses.Text = Replace(String.Join("|", Addies).TrimEnd("|"), "|", vbCr)
                Addresses = String.Join("|", Addies).TrimEnd("|")
            Else
                File.Create(File_AddressDat).Close()
                AddAddress()
            End If
        Catch ex As Exception
            Log(ex)
        End Try
    End Sub

    Private Sub Timer1_Tick(sender As Object, e As System.EventArgs) Handles Timer1.Tick

        If (Addresses.Length < 1) Then
            AddAddress()
        End If

        txtBalance.Text = "Refreshing..."
        txtCurrentPrice.Text = "Refreshing..."
        txtValue.Text = "Refreshing..."
        Me.Refresh()
        SetWindowText()

        If Timer1.Interval = 1 Then
            Timer1.Interval = 10000
        End If

        UpdateData()
        SetWindowText()

    End Sub

    Private Sub AddAddress()
        Form2.ShowDialog()
    End Sub

    Private Sub NewToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles NewToolStripMenuItem.Click
        AddAddress()
    End Sub

    Private Sub ExitToolStripMenuItem1_Click(sender As System.Object, e As System.EventArgs) Handles ExitToolStripMenuItem1.Click
        Me.Close()
    End Sub

    Private Sub Form1_LostFocus(sender As Object, e As System.EventArgs) Handles Me.LostFocus
        SetWindowText()
    End Sub

    Private Sub Log(Ex As Exception)
        Log(Ex.Message)
        Log(Ex.StackTrace)
    End Sub

    Public Sub Log(Ex As String)
        Try

            ListBox1.Items.Add(Ex)
            ListBox1.SelectedIndex = ListBox1.Items.Count - 1

            If Not File.Exists(File_LogDat) Then
                File.Create(File_LogDat).Close()
            End If

            Dim sw As StreamWriter
            sw = File.AppendText(File_LogDat)
            sw.AutoFlush = True
            sw.WriteLine(String.Format("{0} - {1}", Now, Ex))
            sw.Close()

        Catch exc As Exception
            'MsgBox(exc.Message, MsgBoxStyle.Critical, "Error Logging")
        End Try

    End Sub

    Private Sub ShowLogMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles ShowLogMenuItem.Click
        If Me.Height = 116 Then
            Me.Height = 241
            ShowLogMenuItem.Checked = True
        Else
            Me.Height = 116
            ShowLogMenuItem.Checked = False
        End If
    End Sub

    Private Sub NotifyIcon1_MouseClick(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles NotifyIcon1.MouseClick
        If e.Button = Windows.Forms.MouseButtons.Right Then
            Me.Show()
            Me.WindowState = FormWindowState.Normal
        End If
    End Sub

    Private Sub NotifyIcon1_MouseDoubleClick(sender As System.Object, e As System.Windows.Forms.MouseEventArgs) Handles NotifyIcon1.MouseDoubleClick
        Me.Show()
        Me.WindowState = FormWindowState.Normal
    End Sub

    Private Sub ExitToolStripMenuItem2_Click(sender As System.Object, e As System.EventArgs) Handles ExitToolStripMenuItem2.Click
        Me.Close()
    End Sub

    Private Sub AddressToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles AddressToolStripMenuItem.Click
        AddAddress()
    End Sub

    Private Function CalcBalanceChange(PrevBalance As Decimal, NewBalance As Decimal) As String
        Dim Ret As String = String.Empty
        If (PrevBalance > NewBalance) Then
            Ret = " -" & PrevBalance - NewBalance
        Else
            Ret = " +" & NewBalance - PrevBalance
        End If
        Return Ret
    End Function

    Private Sub AboutToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles AboutToolStripMenuItem.Click
        AboutBox1.Show()
    End Sub
End Class